/**
 * @author Haidar Osman
 */
var ClassShape = function(posX, posY, classObj) {
	var that = this;
	this.classObj=classObj;
	this.parentShape = null;	
	this.headerText = new Kinetic.Text({
		x : posX, //+padding,
		y : posY, //+padding+fontsize,
		text : classObj.name,
		fontSize : 20,
		fontFamily : "Calibri",
		textFill : styles.classHeaderTextColor,
		//textStroke : "#444",
		padding : 5,
		align : "left",
		verticalAlign : "middle"
	});
	this.headerRect = new Kinetic.Rect({
		x : posX, // - this.headerText.padding,
		y : posY, // - this.headerText.padding - this.headerText.fontSize,
		width : this.headerText.text.length * this.headerText.fontSize,
		height : 2 * this.headerText.fontSize + 2 * this.headerText.padding,
		fill : styles.classBackgroundColor,
		stroke : styles.classHeaderRectStrokeColor,		
		strokeWidth : 1,
		draggable : true
	});
	this.rightRelationAnchor = new Kinetic.Rect({
		x : posX, // - this.headerText.padding,
		y : posY, // - this.headerText.padding - this.headerText.fontSize,
		width : this.headerText.text.length * this.headerText.fontSize,
		height : 2 * this.headerText.fontSize + 2 * this.headerText.padding,
		//fill : "#00D2FF",

		stroke :"black",
		strokeWidth : 1,
		// draggable : true,
		visible : false
	});
	this.leftRelationAnchor = new Kinetic.Rect({
		x : posX, // - this.headerText.padding,
		y : posY, // - this.headerText.padding - this.headerText.fontSize,
		width : this.headerText.text.length * this.headerText.fontSize,
		height : 2 * this.headerText.fontSize + 2 * this.headerText.padding,
		stroke : "black",
		strokeWidth : 1,
		// draggable : true,
		visible : false
	});
	this.generalizationAnchor = new Kinetic.Rect({
		x : posX, // - this.headerText.padding,
		y : posY, // - this.headerText.padding - this.headerText.fontSize,
		width : this.headerText.text.length * this.headerText.fontSize,
		height : 2 * this.headerText.fontSize + 2 * this.headerText.padding,
		stroke : "black",
		strokeWidth : 1,
		// draggable : true,
		visible : false
	});
	
	this.headerText.on("dblclick", function() {
		var mouseX = that.headerRect.getAbsolutePosition().x + that.headerText.padding + $("#" + that.headerRect.getStage().getContainer().id).prop("offsetLeft");
		var mouseY = that.headerRect.getAbsolutePosition().y + that.headerText.padding + $("#" + that.headerRect.getStage().getContainer().id).prop("offsetTop") - 20;
		var s = "headerRect.y: " + that.headerRect.y + "\nheaderRectAbsolute.y: " + that.headerRect.getAbsolutePosition().y + "\n";
		var formString = "<div id='setClassPopUp' style='position:absolute;top:" + mouseY + "px;left:" + mouseX + "px;z-index:30;'>" + "<br />" + "<input type='text' id='className'  value=\"" + that.classObj.name + "\" autofocus style='width:" + that.headerRect.width + "px; font-size:" + that.headerText.fontSize + "px;  '/>" + "<input type='button' value='save' id='saveClassForm' >" + "<input type='button' value='cancel' id='cancelClassForm' >" + "</div>"

		if($('#className').length !== 0) {
			$('#setClassPopUp').remove();
		}

		$("#" + that.headerRect.getStage().getContainer().id).before(formString);
		$('input#className').focus();
		$('input#className').select();
		$('#className').keydown(function(event) {
			var className = $('input#className').val();
			if(event.which == 13) {
				if(className !== "") {
					that.classObj.name = className;
					that.headerText.text=className;
				} else {
					that.parentShape.removeClass(that.classObj.name);
				}
				$('#setClassPopUp').remove();
				that.update();
			} else if(event.which == 27) {
				$('#setClassPopUp').remove();
			}
		});

		$('#saveClassForm').click(function() {
			that.classObj.name = $('input#className').val();
			that.headerText.text=that.classObj.name;
			$('#setClassPopUp').remove();
			that.update();
		});
		$('#cancelClassForm').click(function() {
			$('#setClassPopUp').remove();
		});
	});
	//adjusting the position of the text
	this.headerText.x = posX + this.headerText.padding;
	this.headerText.y = posY + this.headerText.padding + this.headerText.fontSize;
	//the group that will contain all the element of the shape
	this.group = new Kinetic.Group({
		draggable : true		
	});
	
	
	//revise this for improved performance
	this.group.on("dragmove", function() {
		that.update();
	});
	
	this.group.add(this.headerRect);
	this.group.add(this.headerText);
	this.group.add(this.leftRelationAnchor);
	this.group.add(this.rightRelationAnchor);
	this.group.add(this.generalizationAnchor);
	//class methods
	this.methods = new ShapeArray(this,"methods",this.classObj.methods);
	// this.methods.addMember("");
	this.methodStartY = this.headerRect.y + this.headerRect.height + 10;
	this.methodStartX = this.headerRect.x;
	//class attributes
	this.attributes = new ShapeArray(this,"attributes",this.classObj.attributes);
	// this.attributes.addMember("");
	this.attStartY = this.headerRect.y + this.headerRect.height;
	this.attStartX = this.headerRect.x;
	//this update function will update the positioning and scaling of the shape including all the inner elements
	this.update = function() {
		var layer = this.anchor.getLayer();
		this.headerRect.width = this.headerText.width + 4 * this.headerText.padding;
		currentX = this.headerRect.x;
		currentY = this.headerRect.y + this.headerRect.height;
		this.headerText.x = this.headerRect.x + this.headerText.padding;
		this.headerText.y = this.headerRect.y + this.headerText.padding + this.headerText.fontSize;
		currentWidth = this.headerRect.width;
		var i = 0;
		this.methods.update();
		this.attributes.update();
		var methodsArr = this.methods.members;
		var attsArr = this.attributes.members;		
		if(this.attributes.isVisible) {
			for( i = 0; i < attsArr.length; i++) {
				attsArr[i].rect.x = currentX;
				attsArr[i].rect.y = currentY;
				attsArr[i].signature.x = currentX + attsArr[i].signature.padding;
				attsArr[i].signature.y = currentY + attsArr[i].signature.padding + attsArr[i].signature.fontSize;
				attsArr[i].rect.width = attsArr[i].signature.width + 4 * attsArr[i].signature.padding;
				currentY = currentY + attsArr[i].rect.height;
				if(currentWidth < attsArr[i].rect.width)
					currentWidth = attsArr[i].rect.width;
			}
		} else {
			currentY = currentY + 15;
		}
		if( typeof this.methodImage !== "undefined") {
			this.methodImage.moveToTop();
			this.methodImage.y = currentY;
			this.methodImage.x = currentX;
		}
		if(this.methods.isVisible) {
			for( i = 0; i < methodsArr.length; i++) {
				methodsArr[i].rect.x = currentX;
				methodsArr[i].rect.y = currentY;
				methodsArr[i].signature.x = currentX + methodsArr[i].signature.padding;
				methodsArr[i].signature.y = currentY + methodsArr[i].signature.padding + methodsArr[i].signature.fontSize;
				methodsArr[i].rect.width = methodsArr[i].signature.width + 4 * methodsArr[i].signature.padding;
				currentY = currentY + methodsArr[i].rect.height;
				if(currentWidth < methodsArr[i].rect.width)
					currentWidth = methodsArr[i].rect.width;
			}
		}

		this.headerRect.width = currentWidth;
		for( i = 0; i < methodsArr.length; i++) {
			methodsArr[i].rect.width = currentWidth;
		}
		for( i = 0; i < attsArr.length; i++) {
			attsArr[i].rect.width = currentWidth;
		}
		// this.group.remove();
		if( typeof this.attImage !== "undefined") {
			this.attImage.moveToTop();
			this.attImage.x = this.anchor.x;
		}

		this.currentHeight = currentY - this.headerRect.y;
		// for( i = 0; i < this.outgoingRelations.members.length; i++) {
			// this.outgoingRelations.members[i].update();
			// // this.outgoingRelations.members[i].relationLine.points[0].y = this.headerRect.y;
		// }
		// for( i = 0; i < this.incomingRelations.members.length; i++) {
			// this.incomingRelations.members[i].update();
			// // this.outgoingRelations.members[i].relationLine.points[0].y = this.headerRect.y;
		// }
		// alert(this.headerRect.x);
		this.rightRelationAnchor.x=this.headerRect.x+this.headerRect.width;
		this.rightRelationAnchor.y=this.headerRect.y+this.headerRect.height/2;
		this.rightRelationAnchor.height=this.headerRect.height/2;
		this.rightRelationAnchor.width=10;
		
		this.leftRelationAnchor.x=this.headerRect.x-10;
		this.leftRelationAnchor.y=this.headerRect.y+this.headerRect.height/2;
		this.leftRelationAnchor.height=this.headerRect.height/2;
		this.leftRelationAnchor.width=10;
		
		this.generalizationAnchor.x=this.headerRect.x+ this.headerRect.width/2 - this.headerRect.width*0.1;
		this.generalizationAnchor.y=this.headerRect.y-10;
		this.generalizationAnchor.height=10;
		this.generalizationAnchor.width=this.headerRect.width*0.2;
		//alert(this.parentShape.name);
		// this.parentShape.positions[this.name]={
			// x:that.headerRect.getAbsolutePosition().x,
			// y:that.headerRect.getAbsolutePosition().y
		// }
		// alert(typeof that.parentShape.positions[that.classes[i]]);
		this.parentShape.updateRelations();
		layer.draw();
	}
	//add a method to the shape
	this.addMethod = function(header) {
		this.methods.addMember(header);
	}
	//add an attribute
	this.addAttribute = function(header) {
		this.attributes.addMember(header);
	}
	//adding the resizing anchor to the top left corner of the shape
	this.anchor = new Kinetic.Circle({
		x : that.headerRect.x,
		y : that.headerRect.y,
		stroke : "#666",
		fill : "#ddd",
		strokeWidth : 1,
		radius : 5,
		name : "topLeft",
		draggable : true,
		visible : false
	});
	//anchor events
	this.anchor.on("dragmove", function() {
		// var scaleX=that.headerRect.x-that.anchor.x + that.headerRect.width;
		// scaleX=scaleX/that.headerRect.width;
		var scaleY = that.headerRect.y - that.anchor.y + that.headerRect.height;
		scaleY = scaleY / that.headerRect.height;

		that.headerRect.x = that.anchor.x;
		that.headerRect.y = that.anchor.y;

		that.headerRect.height = that.headerRect.height * scaleY;
		that.headerText.fontSize = (that.headerRect.height - 2 * that.headerText.padding) / 2;
		that.headerRect.width = that.headerText.width + 4 * that.headerText.padding;

		var methodsArr = that.methods.members;
		var i = 0;
		for( i = 0; i < methodsArr.length; i++) {
			methodsArr[i].scale(scaleY);
		}
		var attsArr = that.attributes.members;
		for( i = 0; i < attsArr.length; i++) {
			attsArr[i].scale(scaleY);
		}
		that.update();
	});
	this.anchor.on("mousedown", function() {
		that.group.draggable(false);
		that.anchor.moveToTop();
		var bottomBound = that.headerRect.height
		bottomBound = bottomBound + that.anchor.y - 30;
		that.anchor.dragBounds = {
			bottom : bottomBound
		};
	});
	this.anchor.on("dragend", function() {
		that.group.draggable(true);
	});
	// add hover styling
	this.anchor.on("mouseover", function() {
		that.group.draggable(false);
		var layer = that.anchor.getLayer();
		document.body.style.cursor = "pointer";
		//that.anchor.setStrokeWidth(4);
		layer.draw();
	});
	this.anchor.on("mouseout", function() {
		that.group.draggable(true);
		var layer = that.anchor.getLayer();
		document.body.style.cursor = "default";
		that.anchor.setStrokeWidth(2);
		layer.draw();
	});

	this.group.add(this.anchor);
	//this.parentLayer=layer;

	this.attImage = new Kinetic.Text({
		x : that.methodStartX - 7,
		y : that.methodStartY - 7,
		stroke : "black",
		strokeWidth : 1,
		fill : "white",
		text : "--",
		fontSize : 10,
		fontFamily : "Calibri",
		textFill : "black",
		//textStroke : "black",
		padding : 1,
		align : "center",
		verticalAlign : "middle",
		visible : false,
		name : "methodImage"
	});
	that.attImage.on("click", function() {
		if(that.attributes.isVisible) {
			that.attImage.text = "+";
			that.attributes.hide();
			that.update();

		} else {
			that.attImage.text = "--";
			that.attributes.show();
			that.update();
		}
		that.update();
	});
	this.group.add(this.attImage);

	this.methodImage = new Kinetic.Text({
		x : that.methodStartX - 7,
		y : that.methodStartY - 7,
		stroke : "black",
		strokeWidth : 1,
		fill : "white",
		text : "--",
		fontSize : 10,
		fontFamily : "Calibri",
		textFill : "black",
		//textStroke : "black",
		padding : 1,
		align : "center",
		verticalAlign : "middle",
		visible : false,
		name : "methodImage"
	});
	that.methodImage.on("click", function() {
		if(that.methods.isVisible) {
			that.methodImage.text = "+";
			that.methods.hide();
			// that.update();

		} else {
			that.methodImage.text = "--";
			that.methods.show();
			// that.update();
		}
		that.update();
	});
	this.group.add(this.methodImage);
	// this.outgoingRelations = new RelationArray(this.classObj.outgoingRelations);
	// this.incomingRelations = new RelationArray(this.classObj.incomingRelations);
	this.isMouseOver = false;
	this.group.on("mouseover", function() {
		if(!(that.isMouseOver)) {
			that.isMouseOver = true;
			that.attImage.visible = true;
			that.methodImage.visible = true;
			that.anchor.visible = true;
			that.leftRelationAnchor.visible=true;
			that.rightRelationAnchor.visible=true;
			that.generalizationAnchor.visible=true;
			that.update();
		}
		// alert("mouseover")
	});
	this.group.on("mouseout", function() {
		//that.group.remove(that.attImage);
		that.isMouseOver = false;
		that.attImage.visible = false;
		that.methodImage.visible = false;
		that.anchor.visible = false;
		that.leftRelationAnchor.visible=false;
		that.rightRelationAnchor.visible=false;
		that.generalizationAnchor.visible=false;
		// that.group.remove(that.methodImage);
		that.update();
	});
// 	
	// this.moveTo=function(x,y){
		// that.anchor.getAbsolutePosition().x=x;
		// that.anchor.getAbsolutePosition().y=y;
		// that.headerRect.getAbsolutePosition().x=x;
		// that.headerRect.getAbsolutePosition().y=y;
// 		
		// // that.anchor.x=x;
		// // that.anchor.y=y;
		// // that.headerRect.x=x;
		// // that.headerRect.y=y;
		// that.update();	
	// }
}